/*
 * VK API constructor
 * */
function VkApi() {
    this.apiUrl = "https://api.vk.com/method/";
    this.client_id = "2976728";
    this.redirect_uri = "http://oauth.vk.com/blank.html";
    this.scope = "photos";
    this.response_type = "token";
    this.oauthUrl = "http://api.vk.com/oauth/authorize";
    this.requestTokenUrl = this.oauthUrl +
        "?response_type=" + this.response_type +
        "&scope=" + this.scope +
        "&client_id=" + this.client_id +
        "&redirect_uri=" + this.redirect_uri;
}

var urlUpdateListener = function (id, changeInfo, tab) {
    if (changeInfo.url !== undefined && changeInfo.url.indexOf("#access_token=") != -1) {
        chrome.tabs.executeScript(null, {file: "js/content_script.js"});
        chrome.tabs.onUpdated.removeListener(urlUpdateListener);
    } else {
        // GA
        trackAuthorisationError(changeInfo);
    }
};

/*
 * Call the method to obtain access_token
 * */
VkApi.prototype.authorize = function () {
    if (this.isTokenValid()) {
        addCurrentUserNameToHTML();
        console.log("Token is valid");
    } else {
        chrome.tabs.create({url: this.requestTokenUrl},
            function (tab) {
                chrome.tabs.onUpdated.addListener(urlUpdateListener);
            });
    }
};

/*
 * Save access token
 * */
VkApi.prototype.setToken = function (token) {
    localStorage["access_token"] = token;
};

/*
 * Get stored access token
 * */
VkApi.prototype.getToken = function () {
    return localStorage["access_token"];
};

VkApi.prototype.hasToken = function () {
    return !!this.getToken();
};

/*
 * Set expiration time for access token
 * */
VkApi.prototype.setExpirationTime = function () {
    localStorage["expiration_time"] = new Date().getTime() + 86400000;
};

/*
 * Get expiration time for access token
 * */
VkApi.prototype.getExpirationTime = function () {
    var expirationTime = localStorage["expiration_time"];
    return parseInt(expirationTime, 10);
};

/*
 * Check is access token valid
 * */
VkApi.prototype.isTokenValid = function () {
    return this.getExpirationTime() > new Date().getTime();
};

/*
 * Set current user id
 * */
VkApi.prototype.setUserId = function (id) {
    localStorage["user_id"] = id;
};

/*
 * Get current user id
 * */
VkApi.prototype.getUserId = function () {
    return localStorage["user_id"];
};

/*
 * Clear localStorage
 * */
VkApi.prototype.clearLocalStorage = function () {
    localStorage.clear();
};

/*
 * Sign URL with access token if token valid else call authorize() and sign URL
 * */
VkApi.prototype.signUrl = function (url) {
    if (this.hasToken() && this.isTokenValid()) {
        return url + "&access_token=" + this.getToken();
    } else {
        this.authorize();
        return url + "&access_token=" + this.getToken();
    }
};

/*
 * Return an upload server for an album
 * */
VkApi.prototype.getUploadServer = function (aid) {
    var apiRequest = this.apiUrl +
        "photos.getUploadServer" +
        "?aid=" + aid;
    apiRequest = this.signUrl(apiRequest);
    var xhr = new XMLHttpRequest();
    xhr.open("GET", apiRequest, false);
    xhr.send();
    if (xhr.status === 200 && xhr.readyState === 4) {
        return JSON.parse(xhr.response).response;
    } else {
        return undefined;
    }
};

/*
 * Create an empty album
 * */
VkApi.prototype.createAlbum = function (title, privacy, comment_privacy, numberOfPhotos, callback) {
    var apiRequest = this.apiUrl +
        "photos.createAlbum" +
        "?title=" + title +
        "&privacy=" + privacy +
        "&comment_privacy=" + comment_privacy;
    apiRequest = this.signUrl(apiRequest);

    var xhr = new XMLHttpRequest();
    xhr.open("GET", apiRequest, false);
    xhr.send();

    if (xhr.readyState === 4 && JSON.parse(xhr.response).error === undefined) {
        var jsonResponse = JSON.parse(xhr.response);
        var aid = jsonResponse.response.aid;
        callback(title, aid, numberOfPhotos);
        // GA
        trackCreateAlbum();
        return this.getUploadServer(aid);
    } else if (JSON.parse(xhr.response).error !== undefined && JSON.parse(xhr.response).error.error_code === 9) {
        // GA
        trackCreateAlbumError(JSON.parse(xhr.response).error);
        floodControlErrorPrompt();
    } else {
        // GA
        trackCreateAlbumError(JSON.parse(xhr.response).error);
        return JSON.parse(xhr.response).error;
    }
};

/*
 * Save photos after uploading into an album
 * */
VkApi.prototype.savePhotos = function (response) {
    var apiRequest = this.apiUrl +
        "photos.save" +
        "?aid=" + response.aid +
        "&server=" + response.server +
        "&photos_list=" + response.photos_list +
        "&hash=" + response.hash;
    apiRequest = this.signUrl(apiRequest);
    var xhr = new XMLHttpRequest();
    xhr.addEventListener("load", photoSaveComplete, false);
    xhr.addEventListener("error", photoSaveError, false);

    function photoSaveComplete() {
        if (JSON.parse(xhr.response).error == undefined) {
            addOneUploadedToAlbum(response.aid);
            updateProgressBar(response.aid);
            // GA
            trackSavePhoto();
        } else if (JSON.parse(xhr.response).error.error_code == 6) {
            setTimeout(function () {
                var vk = new VkApi();
                vk.savePhotos(response);
            }, 1000);
        } else {
            // GA
            photoSaveError(JSON.parse(xhr.response).error);
        }
    }

    function photoSaveError() {
        // GA
        trackSavePhotoError(JSON.parse(xhr.response).error.error_msg == undefined ? xhr.response : JSON.parse(xhr.response).error.error_msg);
    }

    xhr.open("GET", apiRequest, true);
    xhr.send();
};

/*
 * Upload one photo
 * */
VkApi.prototype.uploadPhoto = function (uploadUrl, file, albumId) {
    var photoId = albumId + '_' + file.name;
    var counterId = albumId + '_counter';
    var xhr = new XMLHttpRequest();
    xhr.addEventListener("load", uploadComplete, false);
    xhr.addEventListener("error", uploadFailed, false);
    xhr.open("POST", uploadUrl, true);


    // Save photo after uploading
    function uploadComplete() {
        // GA
        trackUploadPhoto();
        var jsonResponse = JSON.parse(xhr.response);
        var vk = new VkApi();
        vk.savePhotos(jsonResponse);
    }

    // Handle error
    function uploadFailed() {
        // GA
        trackUploadPhotoError(JSON.parse(xhr.response).error);
    }

    // Create FormData and add file to it
    var formData = new FormData();
    formData.append("file1", file);

    // Send the FormData
    xhr.send(formData);
};

/*
 * Get user data
 * */
VkApi.prototype.getCurrentUserFullNameAndPhoto = function () {
    var apiRequest = this.apiUrl +
        "users.get" +
        "?uids=" + this.getUserId() +
        "&fields=photo_medium";
    apiRequest = this.signUrl(apiRequest);
    var xhr = new XMLHttpRequest();
    xhr.open("GET", apiRequest, false);
    xhr.send();
    if (xhr.status === 200 && xhr.readyState === 4) {
        return JSON.parse(xhr.response).response;
    } else {
        return undefined;
    }
};

VkApi.prototype.getAlbums = function(){
    var apiRequest = this.apiUrl +
        "photos.getAlbums" +
        "?owner_id=" + this.getUserId() +
        "&need_covers=0";
    apiRequest = this.signUrl(apiRequest);
    var xhr = new XMLHttpRequest();
    xhr.open("GET", apiRequest, false);
    xhr.send();
    if (xhr.status === 200  && xhr.readyState === 4) {
        return JSON.parse(xhr.response).response;
    } else {
        return undefined;
    }
};

VkApi.prototype.getAlbumPhotos = function(albumId){
    var apiRequest = this.apiUrl +
        "photos.get" +
        "?owner_id=" + this.getUserId() +
        "&album_id=" + albumId;
    apiRequest = this.signUrl(apiRequest);
    var xhr = new XMLHttpRequest();
    xhr.open("GET", apiRequest, false);
    xhr.send();
    if (xhr.status === 200  && xhr.readyState === 4) {
        return JSON.parse(xhr.response).response;
    } else {
        return undefined;
    }
};

VkApi.prototype.getAlbumUrl = function (albumId) {
    if (albumId !== undefined) {
        return 'http://vk.com/album' + vk.getUserId() + '_' + albumId;
    } else {
        return 'http://vk.com/albums' + vk.getUserId()
    }
};

VkApi.prototype.getUserUrl = function () {
    return "http://vk.com/id" + vk.getUserId()
};

